﻿package org.kolonitsky.alexey.flashui
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;

    /**
     * MovieClip based scroll bar
     */
    public class Slider extends MovieClip
    {
        
        /** Position minimum value **/
        public var minPos: Number = 0;
        /** Position maximum value **/
        public var maxPos: Number = 100;
        /** Orientation (horizontal | vertical) **/
        public var orientation: String = "vertical";
        
        /** Defined by instance name  **/
        public var track: MovieClip;
        /** Defined by instance name **/
        public var handler: MovieClip;
        
        /** Offset x on handler **/
        private var offX: Number = 0;
        /** Offset y on handler**/
        private var offY: Number = 0;
        
        
        public function Slider() 
        {
            super();
            stop();
            trace("Create");
            addEventListener(Event.ADDED_TO_STAGE, addedToStagheHandler);
        }
        
        /**
         * @property position
         * position bitween min and max
         * @default minPos
         * @see minPos
		 * @see maxPos
         */ 
        private var pos: Number = minPos
        
        public function get position (): Number 
        {
            return pos
        }
        
        public function set position (value:Number): void 
        {
            if (!_enabled) return
            
            value = value < minPos ? minPos : value;
            value = value > maxPos ? maxPos : value;
            
            pos = value;
            var p: Number = pos - minPos;
            var d: Number = maxPos - minPos;
			if (orientation == "horizontal")
	            handler.x = track.x + (p / d) * w() - offX;
			else
				handler.y = track.y + (p / d) * h() - offY;
            dispatchEvent(new Event(Event.CHANGE))
        }


        /**
         * Enabled
         * @default true
         */
        private var _enabled:Boolean = true

        override public function set enabled (value:Boolean): void 
        {
            if (_enabled == value) return
            _enabled = value
            
            if (_enabled) 
            {
                handler.visible = true
                addEventHandlers()
            } 
            else 
            {
                handler.visible = false
                removeEventHandlers()
            }
        }

        override public function get enabled ():Boolean 
        {
            return _enabled
        }
        
        
        protected function updateSliderPosition (point:Point): void 
        {
			if (orientation == "horizontal")
	            position = (point.x / w()) * (maxPos - minPos) + minPos
			else
				position = (point.y / h()) * (maxPos - minPos) + minPos
        }
        
        
        private function addedToStagheHandler(event:Event): void 
        {
            track.useHandCursor = true;
            track.buttonMode = true;
            handler.useHandCursor = true;
            handler.buttonMode = true;
            addEventHandlers();
        }
        
        
        private function addEventHandlers(): void 
        {
            track.addEventListener(MouseEvent.MOUSE_DOWN, onDownSlidebox);
            track.addEventListener(MouseEvent.MOUSE_WHEEL, onWhellMouse);
            handler.addEventListener(MouseEvent.MOUSE_DOWN, onDownSlidebox);
			handler.addEventListener(MouseEvent.MOUSE_WHEEL, onWhellMouse);
        }
        
        
        private function removeEventHandlers(): void 
        {
            track.removeEventListener(MouseEvent.MOUSE_DOWN, onDownSlidebox);
            track.removeEventListener(MouseEvent.MOUSE_WHEEL, onWhellMouse);
            handler.removeEventListener(MouseEvent.MOUSE_DOWN, onDownSlidebox);
			handler.removeEventListener(MouseEvent.MOUSE_WHEEL, onWhellMouse);
        }
        
        
        private function onWhellMouse (event:MouseEvent): void 
        {
            position -= event.delta * 2;
        }
        
        
        private function onDownSlidebox (event:MouseEvent): void 
        {
            if (event.currentTarget == handler)
            {
                offX = event.localX;
                offY = event.localY;
            }
            else 
            {
                offX = handler.width/2;
                offY = handler.height/2;
            }
			var coor:Point = new Point(event.stageX, event.stageY)
            updateSliderPosition(globalToLocal(coor));
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onDragSlidebox);
            stage.addEventListener(MouseEvent.MOUSE_UP, onDropSlidebox);
        }
        
        
        private function onDragSlidebox (event:MouseEvent): void 
        {
            var p: Point = track.globalToLocal(new Point(event.stageX, event.stageY))
            p.x = p.x < offX ? offX : p.x;
            p.x = p.x > w() ? w() : p.x;
            p.y = p.y < offY ? offY : p.y;
            p.y = p.y > h() ? h() : p.y;
            updateSliderPosition(p);
        }
        
        
        private function onDropSlidebox (event:MouseEvent): void 
        {
            var p: Point = track.globalToLocal(new Point(event.stageX, event.stageY))
            p.x = p.x < offX ? offX : p.x;
            p.x = p.x > w() ? w() : p.x;
            p.y = p.y < offY ? offY : p.y;
            p.y = p.y > h() ? h() : p.y;
            updateSliderPosition(p);
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDragSlidebox)
            stage.removeEventListener(MouseEvent.MOUSE_UP, onDropSlidebox)
        }
        
        private function w(): Number 
        {
            return (track.width * track.scaleX) - handler.width + offX;
        }
        
        private function h(): Number
        {
            return (track.height * track.scaleY) - handler.height + offY;
        }
        
    }
}